$(function() {
  const win = window, loc = win.location;
  const endpoint = loc.protocol + "//" + loc.host + loc.pathname + "files"; // 资源地址

  const btnUpload = $('#btnUpload') // 上传按钮
  const inpUpload = $('#inpUpload')[0] // 选择文件
  const progressBar = $('.progress-bar') // 进度条百分比数值
  const fileList = $('#file-list') // 文件列表

  // 格式化字节数
  function formatBytes(bytes, decimals = 2) {
    if (bytes === 0) return '0 Bytes';
    const k = 1024;
    const dm = decimals < 0 ? 0 : decimals;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
  }

  // 重置上传
  function reset() {
    inpUpload.value = ''
    btnUpload.text('上传')
    btnUpload.prop('disabled', false);
    progressBar.width('0%').text('');
  }

  // 新的一行
  function newRow(name, size) {
    size = formatBytes(size)
    const row = document.createElement('tr')
    row.innerHTML = `
      <td class="file-name">${name}</td>
      <td class="file-size">${size}</td>
      <td>
        <a href="${endpoint}/${name}" class="btn btn-danger btn-sm file-url delete">删除</a>
        <a href="${endpoint}/${name}" class="btn btn-info btn-sm file-url rename">重命名</a>
      </td>
    `
    return row
  }

  // 查找指定行
  function findRow(fn) {
    var row = null
    $('tr', fileList).each(function() {
      if (fn($(this))) {
        row = $(this)
        return false
      }
    });
    return row
  }

  // 查找指定文件名的行
  function findRowByName(name) {
    return findRow(function(row) {
      return $('.file-name', row).text() === name
    })
  }

  // 上传
  function upload() {
    const file = inpUpload.files[0]
    if (!file) {
      console.log('No file selected.')
      return // 在重置文件时，IE 会触发 change 事件，此时无文件，只有确实选择了文件才继续。
    }

    btnUpload.prop('disabled', true); // 禁用上传按钮

    var exists = findRowByName(file.name) != null
    if (exists) {
      if (!win.confirm(`文件 ${file.name} 已存在，是否覆盖？`)) {
        reset()
        return
      }
    }

    var formData = new FormData();
    formData.append('file', file);
    var xhr = new XMLHttpRequest();
    xhr.upload.onprogress = function(e) {// 监听进度事件
      if (e.lengthComputable) {
        var pn = (e.loaded / e.total) * 100, percent = pn.toFixed(2) + '%';
        progressBar.width(percent).text(percent);
      }
    };
    xhr.open('POST', endpoint + '/' + file.name, true);
    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    xhr.send(formData);
    xhr.onload = function() {
      if (xhr.status >= 300 || xhr.status < 200) {
        console.error('Upload error: ', xhr.statusText, ", ", xhr.responseText);
        reset()
        win.alert(`文件 ${file.name} 上传失败`)
        return
      }
      if (exists) {
        reset()
        return
      }
      var inserted = false;
      $('tr', fileList).each(function() {
        var fn = $('.file-name', this).text();
        if (file.name.localeCompare(fn) < 0) {
          $(this).before(newRow(file.name, file.size));
          inserted = true
          return false;
        }
      });
      if (!inserted) {
        fileList.append(newRow(file.name, file.size))
      }
      reset()
    }
  }

  // 注册事件
  // ---------------------------------------------------------------------------

  var isSupported = true
  if (!isSupported) { // 浏览器不支持提示消息。
    $('#support-alert').removeClass('hidden')
  }

  // 点击上传按钮：继续/暂停/开始上传/选择文件
  btnUpload.click(() => {  
    if (inpUpload.files.length > 0) {
      upload()
    } else {
      inpUpload.click()
    }
    return false
  })

  // 选择文件后，触发上传
  $(inpUpload).change(upload);

  // 删除文件
  fileList.on('click', '.delete', function() {
    var btn = $(this), tr = btn.parent().parent(), fn = $('.file-name', tr).text(), url = btn.attr('href');
    if (!win.confirm(`确定要删除 ${fn} 吗？`)) {
      return false
    }
    $.ajax({
      url: url,
      type: 'DELETE',
      success: function() {
        tr.remove()
      },
      error: function(xhr, textStatus, errorThrown) {
        win.alert(`[${textStatus}] 删除文件失败`)
      }
    })
    return false
  });

  // 重命名文件：展示输入框
  fileList.on('click', '.rename', function() {
    var btn = $(this), tr = btn.parent().parent();
    var fn = $('.file-name', tr).text(), pos = fn.lastIndexOf('.');
    $('#oldname').val(fn);
    $('#fullurl').val(btn.attr('href'))
    if (pos > 0) {
      $('#newname').val(fn.substring(0, pos));
      $('#extname').text(fn.substring(pos));
    } else {
      $('#newname').val(fn);
      $('#extname').text('');
    }
    $('#rename-dialog').modal('show');
    return false
  });
  // 重命名文件：提交
  $('body').on('click', '.rename-submit', function() {
    var nn = $('#newname').val(), fn = nn + $('#extname').text().trim(), on = $('#oldname').val();
    if (nn == '') {
      alert('请输入新文件名');
      return false;
    }
    if (fn == on) {
      alert('新文件名与旧文件名相同，请输入新名称');
      return false;
    }
    if (/[<>:*?"'|\/]/.test(nn)) {
      alert('文件名不能包含 < > : * ? " \' | / 等字符');
      return false;
    }
    $.ajax({
      url: $('#fullurl').val(),
      type: 'POST',
      contentType: 'application/json',
      data: JSON.stringify({
        'op': 'rename',
        'name': fn
      }),
      success: function() {
        var tr = findRowByName(on);
        if (tr != null) {
          $('.file-name', tr).text(fn);
          $('.file-url', tr).attr('href', `${endpoint}/${fn}`);
        }
        $('#rename-dialog').modal('hide');
      },
      error: function(xhr, textStatus, errorThrown) {
        win.alert(`[${textStatus}] 重命名文件失败`)
        $('#rename-dialog').modal('hide');
      }
    })
    return false
  });

  // 加载页面数据
  $.getJSON(endpoint+"/", function (info) {
    var rows = info.items;
    if (!rows) {
      return
    }
    for (var i in rows) {
      var row = rows[i]
      fileList.append(newRow(row.name, row.size))
    }
    reset();
  })

});
